package cn.javabb.core.service.pay;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.javabb.common.exception.PayException;
import cn.javabb.common.utils.ListUtils;
import cn.javabb.core.base.BaseService;
import cn.javabb.core.constant.PayConstant;
import cn.javabb.core.entity.pay.GoodsDO;
import cn.javabb.core.entity.pay.GoodsQrDO;
import cn.javabb.core.entity.pay.OrderDO;
import cn.javabb.core.entity.sys.LinkDO;
import cn.javabb.core.mapper.pay.OrderMapper;
import cn.javabb.core.plugin.mail.MailUtil;
import cn.javabb.core.plugin.pay.PayUtil;
import cn.javabb.core.plugin.pay.model.PayModel;
import cn.javabb.core.query.OrderQuery;
import cn.javabb.core.service.sys.UserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * @Author javabb
 * @Date 2019/8/12 0012 下午 3:41
 * @Desc
 */
@Slf4j
@Service
public class OrderService extends BaseService<OrderDO> {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private GoodsQrService goodsQrService;
    @Autowired
    private UserService userService;

    @Autowired
    private MailUtil mailUtil;
    /**
     * 分页查询
     * @param query
     * @return
     */
    public Page queryPageBy(OrderQuery query){
        Page p = PageHelper.startPage(query.getPage(),query.getSize());
        orderMapper.queryPageBy(query);
        return p;
    }

    public boolean save(OrderDO order){
        String res = this.insertOrUpdate(order);
        return true;
    }

    /**
     * 获取用户未支付的订单，如果超时了就设置超时
     * @param userId
     * @return
     */
    public OrderDO getNoPayOrder(Integer userId,Integer goodsId){
        OrderDO o = new OrderDO()
                //.setGoodsId(goodsId)
                .setState(PayConstant.ORDER_STATE_NOPAY) // 未支付
                .setUserId(userId);

        OrderDO order = this.queryOne(o);
        // 如果订单已经超时，则订单状态设置为过期。
        if( order!=null
                && DateUtil.between(new Date(),order.getCreateTime(), DateUnit.SECOND)>PayConstant.ORDER_PAY_OVERTIME){
            updateOrderState(order, PayConstant.ORDER_STATE_TIMEOUT);
            return null;
        }
        return order;
    }

    /**
     * 是否存在订单
     * @param goodsId
     * @param userId
     * @return
     */
    public boolean existOrder(Integer goodsId,Integer userId){
        OrderDO order = new OrderDO()
                .setGoodsId(goodsId) //
                .setUserId(userId)
                .setState(PayConstant.ORDER_STATE_SUCCESS);
        if(this.queryCountByWhere(order)>0){
            return true;
        }
        return false;
    }
    public OrderDO getOrderById(String orderId) {
        OrderDO order = this.queryById(orderId);
        GoodsDO goods = goodsService.queryById(order.getGoodsId());
        order.setGoodsName(goods.getGoodsName());
        GoodsQrDO qr = goodsQrService.getGoodsQrByPayNumber(order.getPayNumber()); //取出一条qr
        order.setQr(qr.getImgUrl());
        return order;
    }

    /**
     * 获取订单状态
     * @param orderId
     * @return
     */
    public OrderDO getOrderState(String orderId) {
        OrderDO order = this.queryById(orderId);
        if (order == null) {
            return null;
        }
        // 订单过期控制
        if(order.getState()!=PayConstant.ORDER_STATE_TIMEOUT
                && DateUtil.between(new Date(),order.getCreateTime(), DateUnit.SECOND)>PayConstant.ORDER_PAY_OVERTIME){
            updateOrderState(order, PayConstant.ORDER_STATE_TIMEOUT);
            order.setState(PayConstant.ORDER_STATE_TIMEOUT);
        }
        return order;
    }
    /**
     * 完成支付
     * @param order
     * @param state <br> 0 支付成功 1 正在支付 2 订单取消 3 订单过期
     * @return
     */
    public boolean updateOrderState(OrderDO order,Integer state){
        order.setState(state);
        if(this.updateSelective(order)>0){
            // 如果订单支付成功
            if(state == PayConstant.ORDER_STATE_SUCCESS){
                GoodsDO goods = goodsService.queryById(order.getGoodsId());
                if(goods.getType()== PayConstant.GOODS_TYPE_VIP){
                    userService.updateUserGrade(goods.getUserGroup(),order.getUserId());
                    log.info("更新用户【{}】VIP角色成功",order.getUserId());
                }else if(goods.getType()== PayConstant.GOODS_TYPE_GOLD){
                    userService.updateUserGold(goods.getGold(), order.getUserId());
                    log.info("更新用户【{}】元宝成功",order.getUserId());
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 删除订单
     * @param orderId
     * @return
     */
    public boolean delOrder(String orderId){
        if(this.deleteById(orderId)>0){
            return true;
        }
        return false;
    }
    /**
     * 创建订单
     * @param paytype
     * @param goodsId
     * @param userId
     * @return
     */
    @Transactional
    public OrderDO createOrder(String paytype,Integer goodsId,Integer userId){
        GoodsDO goods = goodsService.queryById(goodsId);
       if(goods == null){
           log.error("获取商品为空");
           return null;
       }
        GoodsQrDO qr = goodsQrService.getNoUseGoodsQr(goods.getGoodsId()); //取出一条qr
        if (qr == null) {
           log.error("获取商品支付二维码为空");
           return null;
        }
        // 根据日期来生成订单号
        String orderId = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
        OrderDO order = new OrderDO()
            .setGoodsId(goodsId)
            .setPayNumber(qr.getPayNumber())
            .setOrderId(orderId)
            .setMoney(goods.getMoney())
            .setPayType(paytype)
            .setUserId(userId)
            .setState(1); // 默认创建的时候是未支付
        int num = this.insertSelective(order);
        if (num > 0) {
            mailUtil.sendOrderMail(orderId);
            return order;
        }
        return null;
    }

    @Transactional
    public OrderDO createOrder2(String paytype,Integer goodsId,Integer userId) throws Exception{
        GoodsDO goods = goodsService.queryById(goodsId);
        //Assert.isNull(goods==null, "产品不存在");
        if (goods == null) {
            return null;
        }
        PayModel pmodel = null;
        try {
            pmodel = PayUtil.createOrder(goods.getMoney(),paytype);
        } catch (Exception ex) {
            throw new PayException("创建订单失败");
        }
        if (pmodel == null) {
            return null;
        }
        //Assert.isNull(pmodel==null,"创建订单调用接口失败啊");
        OrderDO order = new OrderDO();
        order.setGoodsId(goodsId);
        order.setOrderId(pmodel.getOrderId());
        order.setMoney(pmodel.getMoney());
        order.setPayType(paytype);
        order.setQr(pmodel.getQr());
        order.setUserId(userId);
        order.setState(PayConstant.ORDER_STATE_NOPAY); // 默认创建的时候是未创建
        order.setGoodsName(goods.getGoodsName());
        save(order);
        return order;
    }

    /**
     * 更新订单状态
     * @param ids
     * @param state
     * @return
     */
    public boolean updateState(String ids, Integer state) {
        List<String> idList = ListUtils.stringToListString(ids);
        Example ex = new Example(LinkDO.class);
        ex.createCriteria().andIn("orderId", idList);
        OrderDO order = new OrderDO();
        order.setState(state);
        return this.orderMapper.updateByExampleSelective(order, ex)>0?true:false;
    }
}
